package cz.muni.fi.pa165.hauntedhouses.dao;

import cz.muni.fi.pa165.hauntedhouses.entity.House;
import cz.muni.fi.pa165.hauntedhouses.entity.Human;
import cz.muni.fi.pa165.hauntedhouses.util.Util;
import java.util.Collections;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;

/**
 *
 * @author Petr Suchý
 * 
 */
@Repository
public class HumanDAOImpl implements HumanDAO {

    @PersistenceContext(type= PersistenceContextType.EXTENDED)
    private EntityManager em;
    
    
    public void setEntityManager(EntityManager em){
        this.em = em;
    }
    
    @Override
    public void create(Human human){
        Util.validateHuman(human);
        if(human.getId() != null) {
            throw new IllegalArgumentException("This human is already created");
        }   
        em.persist(human);
        em.flush();
        em.detach(human);
    }

    @Override
    public void update(Human human) {
        Util.validateHuman(human);
        if(human.getId() == null) {
            throw new IllegalArgumentException("This human doesnt exist");
        }
        em.merge(human);
        em.flush();
        em.detach(human);
    }

    @Override
    public void remove(Human human) {
        Util.validateHuman(human);
        if(human.getId() == null) {
            throw new IllegalArgumentException("This human doesnt exist");
        }
        Human humanToRemove;
        humanToRemove = em.find(Human.class, human.getId());
        em.remove(humanToRemove);
    }

    @Override
    public Human get(Long id) {
        if(id == null) {
            throw new IllegalArgumentException("ID is NULL");
        }
        if(id < 0) {
            throw new IllegalArgumentException("ID < 0");
        }
        em.flush();
        Human human = em.find(Human.class, id);
        em.flush();
        em.detach(human);
        em.flush();
        return human;
    }

    @Override
    public List<Human> findAll() {        
        Query q = em.createQuery("from Human"); 
        List<Human> humans = q.getResultList();
        return Collections.unmodifiableList(humans);
    }

    @Override
    public List<Human> findByName(String name) {
        if(name == null) {
            throw new IllegalArgumentException("Name is NULL");
        }
        
        Query q = em.createQuery("from Human where name=:name");
        q.setParameter("name", name);
        List<Human> humans = q.getResultList();
        return Collections.unmodifiableList(humans);
    }

    @Override
    public List<Human> findByHouse(House house) {
        Util.validateHouse(house);
        if(house.getId() == null) {
            throw new IllegalArgumentException("House is NULL");
        }
        
        Query q = em.createQuery("from Human where home=:house");
        q.setParameter("house", house);

        List<Human> humans = q.getResultList();
        return Collections.unmodifiableList(humans);
    }    
    
}
